#include "queue.h"

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->_head = NULL;
	pq->_tail = NULL;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);
	while (pq->_head)
	{
		QueueNode* next = pq->_head->_next;
		free(pq->_head);
		pq->_head = next;
	}
	pq->_tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
	if (NULL == newNode)
	{
		perror("QueuePush");
		QueueDestroy(pq);
		exit(-1);
	}
	newNode->_data = x;
	newNode->_next = NULL;
	if (NULL == pq->_tail)
	{
		pq->_head = newNode;
	}
	else
	{
		pq->_tail->_next = newNode;
	}
	pq->_tail = newNode;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->_head);

	QueueNode* next = pq->_head->_next;
	free(pq->_head);
	pq->_head = next;
	if (NULL == pq->_head)
	{
		pq->_tail = NULL;
	}
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->_head);
	return pq->_head->_data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->_tail);
	return pq->_tail->_data;
}

int QueueEmpty(Queue* pq)
{
	return NULL == pq->_head ? 1 : 0;
}

int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->_head;
	int count = 0;
	while (cur != NULL)
	{
		++count;
		cur = cur->_next;
	}
	return count;
}
